#include <iostream>
#include <opencv2/imgproc.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>

#include <opencv2/opencv.hpp>

#define WIDTH 640
#define HEIGHT 480
#define RGB_FRAME_SIZE WIDTH * HEIGHT  * 3
using namespace cv;

int main()
{
    // 输出Content-type 头部
#if 1
    std::cout << "HTTP/1.0 200 OK\r\n";
    std::cout << "Server: Motion/4.1.1\r\n";
    std::cout << "Connection: close\r\n";
    std::cout << "Max-Age: 0\r\n";
    std::cout << "Expires: 0\r\n";
    std::cout << "Cache-Control: no-cache, private\r\n";
    std::cout << "Pragma: no-cache\r\n";
    std::cout << "Content-Type: multipart/x-mixed-replace; boundary=Hello_Harry\r\n\r\n";
#endif

    int shmid;
    char *shmaddr;
    const char *pathname = "/etc/video_share_rgb";
    int proj_id = 65;
    key_t key = ftok(pathname, proj_id);

    // 创建共享内存段
    shmid = shmget(key, RGB_FRAME_SIZE, 0666);
    if (shmid == -1)
    {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    shmaddr = (char *)shmat(shmid, 0, 0);
    if (shmaddr == (void *)-1)
    {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

#if 0
    // 读取视频帧
    int bufLen = WIDTH * HEIGHT * 3 / 2;
    unsigned char *pYuvBuf = new unsigned char[bufLen];
    unsigned char *pBGRBuf = new unsigned char[WIDTH * HEIGHT * 3];
    while (true) 
    {
        memcpy(yuvImg.data, shmaddr, bufLen * sizeof(unsigned char));
        cv::Mat rgbImg;
        cv::cvtColor(yuvImg, rgbImg, COLOR_YUV2BGR_NV12);
        std::vector<uchar> buf;
        cv::imencode(".jpg", rgbImg, buf);
        std::cout << "--Hello_Harry\r\nContent-type: image/jpeg\r\n\r\n";
        std::cout.write(reinterpret_cast<const char *>(buf.data()), buf.size());
        std::cout.flush(); // 刷新输出缓冲区
    }
#endif

#if 1
    cv::Mat rgbImg;
    rgbImg.create(HEIGHT , WIDTH, CV_8UC3);
    while (true)
    {
        memcpy(rgbImg.data, shmaddr, RGB_FRAME_SIZE);
        std::vector<uchar> buf;
        cv::imencode(".jpg", rgbImg, buf);
        std::cout << "--Hello_Harry\r\nContent-type: image/jpeg\r\n\r\n";
        std::cout.write(reinterpret_cast<const char *>(buf.data()), buf.size());
        std::cout.flush(); // 刷新输出缓冲区
    }
#endif

#if 0
    std::cout << "Content-type: video/raw\n\n";
    while (1)
    {
        std::cout.write(reinterpret_cast<const char *>(shmaddr), FRAME_SIZE);
        std::cout.flush(); // 刷新输出缓冲区
    }
#endif

#if 1
    if (shmdt(shmaddr) == -1)
    {
        perror("shmdt failed");
        exit(EXIT_FAILURE);
    }

    // 删除共享内存段
    if (shmctl(shmid, IPC_RMID, 0) == -1)
    {
        perror("shmctl failed");
        exit(EXIT_FAILURE);
    }
#endif

    return 0;
}
